package com.deer.wms.inventory.web;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.deer.wms.base.system.constant.BaseSystemConstant;
import com.deer.wms.base.system.constant.RedisConstants;
import com.deer.wms.base.system.model.Area.AreaInfo;
import com.deer.wms.base.system.model.Cell.CellInfo;
import com.deer.wms.base.system.model.Cell.CellInfoCriteria;
import com.deer.wms.base.system.model.Cell.CellInfoDto;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.model.Pack.PackDetail;
import com.deer.wms.base.system.model.Pack.PackDetail2;
import com.deer.wms.base.system.model.Shelf.ShelfInfo;
import com.deer.wms.base.system.service.*;
import com.deer.wms.file.configurer.FileSetting;
import com.deer.wms.intercept.annotation.Authority;
import com.deer.wms.intercept.annotation.User;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.constant.InventoryConstant;
import com.deer.wms.inventory.model.Inventory.*;
import com.deer.wms.inventory.model.combinePallet.BoxResultInsertData;
import com.deer.wms.inventory.model.combinePallet.CombinePalletTask;
import com.deer.wms.inventory.model.move.Move;
import com.deer.wms.inventory.service.*;
import com.deer.wms.project.root.annotaiton.MyAnnotation;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.core.result.Result;
import com.deer.wms.project.root.core.result.ResultGenerator;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.project.root.util.*;
import com.deer.wms.system.manage.model.organization.Organization;
import com.deer.wms.system.manage.service.CellLedService;
import com.deer.wms.system.manage.service.OrganizationService;
import com.deer.wms.system.manage.test.CellLedCriteria;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import jxl.format.CellFormat;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.persistence.Column;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
* Created by 郭靖勋 on 2019/12/18.
*/
@Api(description = "库存信息api接口")
@RestController
@RequestMapping("/inventorys")
public class InventoryController {
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private InventoryTransactService inventoryTransactService;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private ItemInfoService itemInfoService;
    @Autowired
    private PackDetailService packDetailService;
    @Autowired
    private CellInfoService cellInfoService;
    @Autowired
    private FileSetting fileSetting;
    @Autowired
    private SerialNoService serialNoService;
    @Autowired
    private ItemBatchService itemBatchService;
    @Autowired
    private CombinePalletTaskService combinePalletTaskService;
    @Autowired
    AreaInfoService areaInfoService;
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/insert")
    public Result add(@RequestBody Inventory inventory) {
        inventoryService.save(inventory);
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/delete")
    public Result delete(Integer id) {
        inventoryService.removeById(id);
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/update")
    public Result update(@RequestBody Inventory inventory) {
        inventoryService.updateById(inventory);
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/detail")
    public Result detail(Integer id) {
        Inventory inventory = inventoryService.getById(id);
        return ResultGenerator.genSuccessResult(inventory);
    }

    @ApiOperation(value = "获取收货区库存")
    @GetMapping("/getAccept")
    public Result getAccept(Integer id, Integer wareId) {
        Inventory inventory = inventoryService.getAccept(id, wareId);
        return ResultGenerator.genSuccessResult(inventory);
    }

    @ApiOperation("按条件查询库存")
    @GetMapping("/list")
    public Result list(InventoryCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<InventoryDto> list = inventoryService.findList(criteria);

        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    /**
     * 库存有效期预警查询
     * @param  criteria     查询条件
     * @return   返回结果
     * @since  1.0
     * @deprecated
     */
    @ApiOperation("库存有效期预警查询")
    @GetMapping("/inventoryEarlyList")
    public Result inventoryEarlyList(InventoryEarlyCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<InventoryEarlyDto> list = inventoryService.inventoryEarlyList(criteria);
        //库存预警状态赋值
//        List<InventoryEarlyDto> lists= inventoryService.insertEarlyState(list);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }
    /**
     * 库存有效期预警导出方法
     * @param  response     查询条件
     * @return   返回结果
     * @since  1.0
     * @deprecated
     */
    @GetMapping("/exportExcel")
    public String exportExcel(HttpServletResponse response, Integer organizationId, String itemCode, String itemName, String cellCode, String batchName,String boxCode,String startTime,String endTime,Integer earlyState) throws Exception{
        inventoryService.exportExcel(response,organizationId,itemCode,itemName,cellCode,batchName,boxCode,startTime,endTime,earlyState);
        return "";
    }
    @ApiOperation("按条件查询库存,并汇总库存")
    @GetMapping("/list/sumQty")
    public Result listSumQty(InventoryCriteria criteria) {
        List<InventoryDto> list = inventoryService.findList(criteria);

        double sumQty = list.stream().mapToDouble(value -> value.getQuantity()).summaryStatistics().getSum();
        return ResultGenerator.genSuccessResult().setMessage(NumberUtil.decimalFormat("#", sumQty));
    }

    @GetMapping("/report/data")
    public Result getReportData(@RequestParam Integer wareId) {
        Map<String, Object> map = new HashMap<>();
        //库存总数量    SKU总数量
        InventoryCriteria criteria = new InventoryCriteria();
        criteria.setCellUseType(BaseSystemConstant.CELL_USE_TYPE_STORE);
        Double allStock = inventoryService.findAllStock(wareId);
        Integer allSKUs = inventoryService.findAllSKUs(wareId);
        map.put("allStockQty", ObjectUtil.isNull(allStock) ? 0.0 : allStock);
        map.put("allSKUQty", allSKUs);

        //库位利用率
        Double allStockCells = Double.valueOf(inventoryService.findAllStockCells(wareId));
        List<CellInfo> byCellUseTypes = cellInfoService.list(new QueryWrapper<CellInfo>().eq("cell_use_type", BaseSystemConstant.CELL_USE_TYPE_STORE));
        BigDecimal cellRatio = NumberUtil.round(allStockCells/byCellUseTypes.size(), 2).multiply(new BigDecimal(100));
        map.put("cellRatio", cellRatio);

        //SKU类型占比
        List<Inventory> topSkuInv = inventoryService.getTopSku(wareId, 5);
        map.put("topSku", topSkuInv);

        return ResultGenerator.genSuccessResult(CommonCode.SUCCESS, map);
    }

    @Autowired
    private CellLedService cellLedService;

    @ApiOperation(value = "库存查询亮灯", notes = "卓品电子料架")
    @PostMapping("/led/operate/up")
    public Result operate(@RequestBody InventoryCriteria criteria){
        //全部灭灯
        QueryWrapper<CellInfo> qw = new QueryWrapper<>();
        List<CellInfo> cellInfos = cellInfoService.list(qw.likeRight("cell_code", "2"));
        List<String> collect = cellInfos.stream().map(CellInfo::getCellCode).collect(Collectors.toList());
        cellLedService.ledControl(collect, null, null, 0);


        criteria.setCellUseType(BaseSystemConstant.CELL_USE_TYPE_STORE);
        List<InventoryDto> list = inventoryService.findList(criteria);
        List<String> cellCodes = new ArrayList<>();
        for (InventoryDto inv : list) {
            if (StringUtils.startsWith(inv.getCellCode(), "2")) {
                cellCodes.add(inv.getCellCode());
            }
        }

        cellLedService.ledControl(cellCodes, "2", -1L, 1);

        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "全部灭灯", notes = "卓品电子料架")
    @PostMapping("/led/operate/offAll")
    public Result operate3(@RequestBody InventoryCriteria criteria){
        QueryWrapper<CellInfo> qw = new QueryWrapper<>();
        List<CellInfo> cellInfos = cellInfoService.list(qw.likeRight("cell_code", "2"));
        List<String> collect = cellInfos.stream().map(CellInfo::getCellCode).collect(Collectors.toList());
        cellLedService.ledControl(collect, null, null, 0);

        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "库存查询灭灯", notes = "卓品电子料架")
    @PostMapping("/led/operate/off")
    public Result operate2(@RequestBody InventoryCriteria criteria){
        criteria.setCellUseType(BaseSystemConstant.CELL_USE_TYPE_STORE);
        List<InventoryDto> list = inventoryService.findList(criteria);
        List<String> cellCodes = new ArrayList<>();
        for (InventoryDto inv : list) {
            if (StringUtils.startsWith(inv.getCellCode(), "2")) {
                cellCodes.add(inv.getCellCode());
            }
        }
        cellLedService.ledControl(cellCodes, "2", -1L, 0);

        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "解冻", notes = "WEB")
    @PostMapping("/notFreeze")
    public Result notFreeze(@RequestBody InventoryCriteria criteria){
        Inventory inventory = inventoryService.getById(criteria.getInventoryId());
        if (inventory.getFreezeQuantity() < criteria.getFreezeQuantity()) {
            throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR, "解冻数量不能大于已冻结数量");
        }
        double qty = inventory.getFreezeQuantity() - criteria.getFreezeQuantity();
        inventory.setFreezeQuantity(qty);
//        System.out.println(criteria.getFreezeQuantity());
//        System.out.println(inventory);
        inventoryService.updateById(inventory);

        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation("根据追踪号查询")
    @GetMapping("/lpnStock")
    public Result getLpnStock(InventoryCriteria criteria) {
        Inventory inventory = inventoryService.getOneByField("box_code", criteria.getBoxCode());

        return ResultGenerator.genSuccessResult(inventory);
    }

    @GetMapping("/checkList")
    public Result checkList(InventoryCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<Inventory> list = inventoryService.checkList(criteria);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "汇总库存")
    @GetMapping("/sumList")
    public Result SumList(InventoryCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<Inventory> list = inventoryService.findSame(criteria);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "查询待出库的库存")
    @GetMapping("/toOutStock")
    public Result toOutStock(InventoryCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<InventoryToOutDto> list = inventoryService.findToOutStock(criteria);
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "查询待上架的库存")
    @GetMapping("/toUpperStock")
    public Result ToUpperStock(InventoryCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<InventoryToUpperDto> list = inventoryService.findToUpperStock(criteria);

        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "查询已出库库存")
    @GetMapping("/toOutBackStock")
    public Result toOutBackStock(InventoryCriteria criteria) {

        List<InventoryDto> list = inventoryService.inventoriesForOut(criteria.getBoxCode());
        List<InventoryDto> list2 = new ArrayList<>();
        if (list.size() > 0) {
            list2.add(list.get(0));
        }

        PageInfo pageInfo = new PageInfo(list2);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @ApiOperation(value = "按库存的使用类型查询库存")
    @GetMapping("/CellUseTypeList")
    public Result CellUseTypeList(InventoryCriteria criteria) {
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        List<InventoryDto> list = inventoryService.findByCellUseType(criteria);

        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }


    @ApiOperation(value = "库存导入", notes = " 库存导入")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @Transactional
    @PostMapping("/importInventory")
    public Result importInventory(InventoryImport excel, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER);
        }
        jxl.Workbook billWorkbook = null;
        String msg = "Excel 内容有问题，无法导入！";

        try {
            billWorkbook = jxl.Workbook.getWorkbook(excel.getModel().getInputStream());
            jxl.Sheet billSheet = billWorkbook.getSheet(0);

            int rows = billSheet.getRows();

            Integer rowCount = 0;
            for (int i = 1; i < rows; i++) {
                String content = ExcelUtils.getCellString(billSheet, 0, i).trim();
                if (StringUtils.isEmpty(content)) {
                    break;
                }
                rowCount++;
            }
            for (int i = 2; i < rowCount + 2; i++) {

                String organizationName = ExcelUtils.getCellString(billSheet, 0, 0).trim();
                Integer organizationId = null;
                QueryWrapper<Organization> qw = new QueryWrapper<>();
                qw.eq("organizationName", organizationName);
                Organization organization = organizationService.getOne(qw);
                organizationId = organization.getOrganizationId();

                String itemName = ExcelUtils.getCellString(billSheet, 1, i).trim();
                String itemCode = null;
                ItemInfo itemInfo = itemInfoService.findBy("item_name", itemName);
                itemCode = itemInfo.getItemCode();

                String packDescribe = ExcelUtils.getCellString(billSheet, 2, i);
                if (packDescribe == null) {
                    msg = "缺少单位！" + packDescribe;
                    throw new Exception();
                }

                PackDetail packDetail = packDetailService.findBy("pack_describe", packDescribe);

                Double quantity = ExcelUtils.getCellDouble(billSheet, 3, i);

                String boxCode = ExcelUtils.getCellString(billSheet, 4, i).trim();
                String lpn = ExcelUtils.getCellString(billSheet, 5, i).trim();

                String cellCode = ExcelUtils.getCellString(billSheet, 6, i);
                if (cellCode == null) {
                    msg = "缺少货位！" + cellCode;
                    throw new Exception();
                }
//                CellInfo cellInfo = cellInfoService.findBy("cellName",cellName);


                Inventory inventory = new Inventory();
                inventory.setWareId(excel.getWareId());
                inventory.setWareName(excel.getWareName());
                inventory.setOrganizationId(organizationId);
                inventory.setOrganizationName(organizationName);
                inventory.setItemCode(itemCode);
                inventory.setItemName(itemName);
                inventory.setBatchName("CSKC");
                inventory.setCellCode(cellCode);
                inventory.setBoxCode(boxCode);
                inventory.setLpn(lpn);
                inventory.setPackDetailId(packDetail.getPackDetailId());
                inventory.setPackDescribe(packDescribe);
                inventory.setQuantity(quantity);
                inventory.setState(0);


                inventoryService.save(inventory);
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(CommonCode.WRONG_EXCEL_CONTENT, msg);

        } finally {
            billWorkbook.close();
        }

        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "库存导出", notes = "库存导出")
    @GetMapping("/exportInventory")
    public Result exportInboundExcel(InventoryCriteria criteria, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }
        criteria.setPageNum(1);
        criteria.setPageSize(10000);

        List<InventoryDto> list = inventoryService.findList(criteria);

        String staticPath = fileSetting.getStaticFileDir();
        String downloadPath = "\\download\\inventory.xls";
        String modelPath = "\\model\\inventoryModel.xls";
        try {
            String modelFilePath = staticPath + modelPath;
            String filePath = staticPath + downloadPath;

            jxl.Workbook workbook = jxl.Workbook.getWorkbook(new java.io.File(modelFilePath));
            WritableWorkbook copy = jxl.Workbook.createWorkbook(new java.io.File(filePath), workbook);

            WritableSheet wSheet = copy.getSheet(0);
            CellFormat format = wSheet.getCell(1, 1).getCellFormat();
            DecimalFormat two = new DecimalFormat("#.##");

            Double sum = 0.0;
            for (int i = 0; i < list.size(); i++) {

                wSheet.insertRow(i + 2);

                InventoryDto inventory = list.get(i);

                String indexStr = Integer.toString(i + 1);
                String wareName = "-";
                if (inventory.getWareName() != null) {
                    wareName = inventory.getWareName();
                }
                String organizationName = "-";
                if (inventory.getOrganizationName() != null) {
                    organizationName = inventory.getOrganizationName();
                }
                String itemName = "-";
                if (inventory.getItemName() != null) {
                    itemName = inventory.getItemName();
                }
                String itemCode = "-";
                if (inventory.getCellCode() != null) {
                    itemCode = inventory.getItemCode();
                }
                String batchName = "-";
                if (inventory.getBatchName() != null) {
                    batchName = inventory.getBatchName();
                }

                String quantity = "-";
                if (inventory.getQuantity() != null) {
                    quantity = Double.toString(inventory.getQuantity());
                }

                String packDescribe = "-";
                if (inventory.getPackDescribe() != null) {
                    packDescribe = inventory.getPackDescribe();
                }
                String allotQuantity = "-";
                if (inventory.getAllotQuantity() != null) {
                    allotQuantity = Double.toString(inventory.getAllotQuantity());
                }
                String freezeQuantity = "-";
                if (inventory.getFreezeQuantity() != null) {
                    freezeQuantity = Double.toString(inventory.getFreezeQuantity());
                }
                String cellCode = "-";
                if (inventory.getCellCode() != null) {
                    cellCode = inventory.getCellCode();
                }
                String boxCode = "-";
                if (inventory.getBoxCode() != null) {
                    boxCode = inventory.getBoxCode();
                }
                String lpn = "-";
                if (inventory.getLpn() != null) {
                    lpn = inventory.getLpn();
                }


                Label indexLabel = new Label(0, i + 2, indexStr);
                Label wareNameLabel = new Label(1, i + 2, wareName);
                Label organizationNameLabel = new Label(2, i + 2, organizationName);
                Label itemNameLabel = new Label(3, i + 2, itemName);
                Label itemCodeLabel = new Label(4, i + 2, itemCode);
                Label batchNameLabel = new Label(5, i + 2, batchName);
                Label quantityLabel = new Label(6, i + 2, quantity);
                Label packDescribeLabel = new Label(7, i + 2, packDescribe);
                Label allotQuantityLabel = new Label(8, i + 2, allotQuantity);
                Label freezeQuantityLabel = new Label(9, i + 2, freezeQuantity);
                Label cellCodeLabel = new Label(10, i + 2, cellCode);
                Label boxCodeLabel = new Label(11, i + 2, boxCode);
                Label lpnLabel = new Label(12, i + 2, lpn);

                indexLabel.setCellFormat(format);
                wareNameLabel.setCellFormat(format);
                organizationNameLabel.setCellFormat(format);
                itemNameLabel.setCellFormat(format);
                itemCodeLabel.setCellFormat(format);
                batchNameLabel.setCellFormat(format);
                quantityLabel.setCellFormat(format);
                packDescribeLabel.setCellFormat(format);
                allotQuantityLabel.setCellFormat(format);
                freezeQuantityLabel.setCellFormat(format);
                cellCodeLabel.setCellFormat(format);
                boxCodeLabel.setCellFormat(format);
                lpnLabel.setCellFormat(format);

                wSheet.addCell(indexLabel);
                wSheet.addCell(wareNameLabel);
                wSheet.addCell(organizationNameLabel);
                wSheet.addCell(itemNameLabel);
                wSheet.addCell(itemCodeLabel);
                wSheet.addCell(batchNameLabel);
                wSheet.addCell(quantityLabel);
                wSheet.addCell(packDescribeLabel);
                wSheet.addCell(allotQuantityLabel);
                wSheet.addCell(freezeQuantityLabel);
                wSheet.addCell(cellCodeLabel);
                wSheet.addCell(boxCodeLabel);
                wSheet.addCell(lpnLabel);
            }


            String nowStr = "打印日期：" + DateUtils.getNowDateString();
            Label dateLabel = new Label(0, list.size() + 3, nowStr);
            dateLabel.setCellFormat(format);
            wSheet.addCell(dateLabel);

            copy.write();
            copy.close();
            workbook.close();

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
        }

        return ResultGenerator.genSuccessResult(downloadPath);
    }

    @ApiOperation(value = "库存移动", notes = "库存移动")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @PostMapping("/move/inventory")
    public Result moveInventory(@RequestBody Move move, @ApiIgnore @User CurrentUser currentUser) {
        if (currentUser == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER, null);
        }

        Integer createUserId = currentUser.getUserId();
        String createUserName = currentUser.getUserName();
        String createTime = DateUtils.getNowDateTimeString();

        InventoryTransact inventoryTransact = new InventoryTransact();
//        BeanUtils.copyProperties(moveInventory, inventoryTransact);
        inventoryTransact.setTransactType(InventoryConstant.TRANSACT_TYPE_MOVE);
        inventoryTransact.setItemCode(move.getItemCode());
        inventoryTransact.setItemName(move.getItemName());
        inventoryTransact.setWareId(move.getWareId());
        inventoryTransact.setWareName(move.getWareName());
        inventoryTransact.setToWareId(move.getWareId());
        inventoryTransact.setToWareName(move.getWareName());
        inventoryTransact.setFromCellCode(move.getCellCode());
        inventoryTransact.setToCellCode(move.getToCellCode());
        inventoryTransact.setFromOrganizationId(move.getOrganizationId());
        inventoryTransact.setFromOrganizationName(move.getOrganizationName());
        inventoryTransact.setToOrganizationId(move.getOrganizationId());
        inventoryTransact.setToOrganizationName(move.getOrganizationName());
        inventoryTransact.setFromBatchId(move.getBatchId());
        inventoryTransact.setFromBatchName(move.getBatchName());
        inventoryTransact.setToBatchId(move.getBatchId());
        inventoryTransact.setToBatchName(move.getBatchName());
        inventoryTransact.setFromBoxCode(move.getBoxCode());
        inventoryTransact.setToBoxCode(move.getToBoxCode());
        inventoryTransact.setFromPackDetailId(move.getPackDetailId());
        inventoryTransact.setFromPackDescribe(move.getPackDescribe());
        inventoryTransact.setToPackDetailId(move.getPackDetailId());
        inventoryTransact.setToPackDescribe(move.getPackDescribe());
        inventoryTransact.setFromTransRatio(move.getTransRatio());
        inventoryTransact.setToTransRatio(move.getTransRatio());
        inventoryTransact.setCreateUserId(createUserId);
        inventoryTransact.setCreateUserName(createUserName);
        inventoryTransact.setCreateTime(createTime);
        inventoryTransact.setFromQuantity(move.getQuantity());
        inventoryTransact.setToQuantity(move.getToQuantity());
        int inventoryId = inventoryTransactService.run(inventoryTransact);
        List<String> serialNos = move.getSerialNos();
        if (serialNos != null && serialNos.size() != 0) {
            serialNoService.serialNoRecored(move.getSerialNos(), createUserId,
                    createUserName, null, inventoryId, InventoryConstant.SERIALNO_TRANSFER);
        }
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "查询冻结货位", notes = "查询冻结货位")
    @GetMapping("/findByFreeze")
    public Result findByFreeze(InventoryCriteria criteria) {
        List<Inventory> list = inventoryService.findByCellCode(criteria);
        return ResultGenerator.genSuccessResult(list);
    }

    @ApiOperation(value = "查询解冻货位", notes = "查询解冻货位")
    @GetMapping("/findByRelease")
    public Result findByRelease(InventoryCriteria criteria) {
        List<Inventory> list = inventoryService.findByCellCodeAndState(criteria);
        return ResultGenerator.genSuccessResult(list);
    }

    @ApiOperation(value = "货位冻结", notes = "货位冻结")
    @GetMapping("/freezeCell")
    public Result freezeCell(Integer inventoryId, Double freezeQuantity1, @ApiIgnore @User CurrentUser currentUser) {
        Inventory inventory = inventoryService.getById(inventoryId);
        inventory.setFreezeQuantity(inventory.getFreezeQuantity() + freezeQuantity1);
        inventory.setQuantity(inventory.getQuantity() - freezeQuantity1);

        if (inventory.getQuantity() == 0) {
            inventory.setState(2);
        } else {
            inventory.setState(1);
        }
        inventoryService.updateById(inventory);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "货位批量冻结", notes = "货位批量冻结")
    @GetMapping("/freezeCells")
    public Result freezeCells(String cellCode, Integer wareId, @ApiIgnore @User CurrentUser currentUser) {

        InventoryCriteria criteria = new InventoryCriteria();
        criteria.setCellCode(cellCode);
        criteria.setWareId(wareId);
        List<Inventory> inventorys = inventoryService.findByCellCode(criteria);
        for (Inventory inventory : inventorys) {
            inventory.setFreezeQuantity(inventory.getFreezeQuantity() + inventory.getQuantity());
            inventory.setQuantity(0.0);
            inventory.setState(2);
            inventoryService.updateById(inventory);
        }

        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "货位解冻", notes = "货位解冻")
    @GetMapping("/releaseCell")
    public Result releaseCell(Integer inventoryId, Double freezeQuantity1, @ApiIgnore @User CurrentUser currentUser) {
        Inventory inventory = inventoryService.getById(inventoryId);
        inventory.setFreezeQuantity(inventory.getFreezeQuantity() - freezeQuantity1);
        inventory.setQuantity(inventory.getQuantity() + freezeQuantity1);
        if (inventory.getFreezeQuantity() == 0) {
            inventory.setState(0); //正常
        }
        if (inventory.getQuantity() != 0) {
            inventory.setState(1); //部分冻结
        }
        inventoryService.updateById(inventory);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "货位批量解冻", notes = "货位批量解冻")
    @GetMapping("/releaseCells")
    public Result releaseCells(String cellCode, Integer wareId, @ApiIgnore @User CurrentUser currentUser) {
        InventoryCriteria criteria = new InventoryCriteria();
        criteria.setCellCode(cellCode);
        criteria.setWareId(wareId);
        List<Inventory> inventorys = inventoryService.findByCellCodeAndState(criteria);
        for (Inventory inventory : inventorys) {
            inventory.setQuantity(inventory.getFreezeQuantity());
            inventory.setFreezeQuantity(0.0);
            inventory.setState(0);
            inventoryService.updateById(inventory);
        }

        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "货位锁定", notes = "货位锁定")
    @GetMapping("/lockCell")
    public Result lockCell(String cellCode) {

        InventoryCriteria criteria = new InventoryCriteria();
        criteria.setCellCode(cellCode);
        List<Inventory> inventorys = inventoryService.findByCellCode(criteria);
        if (inventorys.size() > 0) {
            throw new ServiceException(CommonCode.CELL_ERROR);
        }
        CellInfo cellInfo = cellInfoService.findBy("cell_code", cellCode);
        cellInfo.setState("disable");
        cellInfoService.updateById(cellInfo);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "货位解锁", notes = "货位解锁")
    @GetMapping("/unlockCell")
    public Result unlockCell(String cellCode) {

        CellInfo cellInfo = cellInfoService.findBy("cell_code", cellCode);
        cellInfo.setState("enable");
        cellInfoService.updateById(cellInfo);
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "同步库存和批次的质检状态 传inventoryId", notes = "同步库存和批次的质检状态 传inventoryId")
    @PostMapping("/synchronization")
    public Result synchronization(BatchData batchData) {
        for (int i = 0; i < batchData.getInventoryIds().size(); i++) {
            Inventory inventory = inventoryService.getById(i);
            ItemBatch itemBatch = itemBatchService.getById(inventory.getBatchId());
            itemBatch.setQcState(batchData.getQcState());
            itemBatchService.updateById(itemBatch);
        }
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "库存安全报表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "access-token", value = "token", paramType = "header", dataType = "String", dataTypeClass = String.class, required = true)
    })
    @Authority
    @PostMapping("/inventorySafetyReport")
    public Result inventorySafetyReport(@RequestBody InventoryCriteria criteria, @User CurrentUser user) {
        if (user == null) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER);
        }
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        return ResultGenerator.genSuccessResult(new PageInfo(inventoryService.inventorySafetyList(criteria)));
    }


    @ApiOperation(value = "查询待合并库存")
    @GetMapping("/palletsToCombine")
    public Result palletsToCombine(InventoryCriteria criteria, @User CurrentUser currentUser) {
//        if (currentUser == null) {
//            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER);
//        }
        PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
        criteria.setMaxQuantity(1000.0);
        criteria.setMaxWeight(1000.0);
        List<Inventory> inventories = inventoryService.palletsToCombine(criteria);
        PageInfo pageInfo = new PageInfo(inventories);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/inventoriesWithBoxCode")
    public Result inventoriesWithBoxCode(String boxCode) {
        List<Inventory> inventories = inventoryService.inventoriesWithBoxCode(boxCode);
        PageInfo pageInfo = new PageInfo(inventories);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @PostMapping("/boxResult")
    @Transactional
    public Result boxResult(@RequestBody BoxResultInsertData insertData) {
        String boxCode = insertData.getBoxCode();
        String boxCode2 = insertData.getBoxCode2();
        List<Inventory> inventories = insertData.getInventoryList();
        List<Inventory> inventories2 = insertData.getInventoryList2();
        for (Inventory inventory : inventories) {
            inventory.setBoxCode(boxCode);
            inventoryService.updateById(inventory);
        }
        for (Inventory inventory : inventories2) {
            inventory.setBoxCode(boxCode2);
            inventoryService.updateById(inventory);
        }
        List<CombinePalletTask> tasks = combinePalletTaskService.taskWithBoxCode(boxCode);
        CombinePalletTask task = tasks.get(0);
        task.setCompleteTime(DateUtils.getNowDateTimeString());
        combinePalletTaskService.updateById(task);
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/findGroupByWareOrgItem")
    @Transactional
    public Result boxResult(InventoryCriteria criteria) {
        List<GroupByWareOrgItem> list = inventoryService.findGroupByWareOrgItem(criteria);
        for (GroupByWareOrgItem groupByWareOrgItem : list) {

            List<PackDetail2> packDetailList = packDetailService.findByCode2(groupByWareOrgItem.getPackCode());

            groupByWareOrgItem.setPackDetails(packDetailList);
        }
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/canOut")
    @Transactional
    public Result canOut(InventoryCriteria criteria) {
        List<InventoryDto> list = inventoryService.canOut(criteria);

        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    private static Integer exportCount = 1;

    @GetMapping("/exportFindGroupByWareOrgItem")
    @Transactional
    public Result exportFindGroupByWareOrgItem(InventoryCriteria criteria) throws IOException {
        criteria.setPageNum(1);
        criteria.setPageSize(1000000);
        List<GroupByWareOrgItem> list = inventoryService.findGroupByWareOrgItem(criteria);
        String staticPath = fileSetting.getStaticFileDir();
        String downloadPath = File.separator + "download" + File.separator + "inventory" + ".xlsx";
        exportCount += 1;
        String filePath = staticPath + downloadPath;

        Workbook workbook = new SXSSFWorkbook();
        try {
            Sheet sheet = workbook.createSheet("First");
            sheet.createRow(0);
            FileOutputStream out = new FileOutputStream(filePath);
            workbook.write(out);

            String[] title = {"仓库", "货主", "物料", "料号", "总数", "分配数", "冻结数", "待上架数", "待发运数", "单位"};
            ExcelUtils excelUtils = new ExcelUtils(new File(filePath));
            excelUtils.writeArrayToExcel(0, true, 0, 0, title);

            for (int i = 0; i < list.size(); i++) {
                GroupByWareOrgItem box = list.get(i);
                String orgName = box.getOrganizationName() == null ? "" : box.getOrganizationName();
                String wareName = box.getWareName() == null ? "" : box.getWareName();
                String itemName = box.getItemName() == null ? "" : box.getItemName();
                String itemCode = box.getItemCode() == null ? "" : box.getItemCode();
                String totalQuantity = box.getTotalQuantity() == null ? "" : box.getTotalQuantity().toString();
                String totalAllotQuantity = box.getTotalAllotQuantity() == null ? "" : box.getTotalAllotQuantity().toString();
                String totalFreezeQuantity = box.getTotalFreezeQuantity() == null ? "" : box.getTotalFreezeQuantity().toString();
                String totalAcceptQuantity = box.getTotalAcceptQuantity() == null ? "" : box.getTotalAcceptQuantity().toString();
                String totalOutQuantity = box.getTotalOutQuantity() == null ? "" : box.getTotalOutQuantity().toString();
                String packDescribe = box.getPackDescribe() == null ? "" : box.getPackDescribe();

                String[] row = {orgName,
                        wareName,
                        itemName,
                        itemCode,
                        totalQuantity,
                        totalAllotQuantity,
                        totalFreezeQuantity,
                        totalAcceptQuantity,
                        totalOutQuantity,
                        packDescribe};
                excelUtils.insertRowWithFormat(0, i + 1);
                excelUtils.writeArrayToExcel(0, true, i + 1, 0, row);
            }
            excelUtils.writeAndClose();
            ((SXSSFWorkbook) workbook).dispose();
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        } finally {
            workbook.close();
        }
        return ResultGenerator.genSuccessResult(downloadPath);

    }

    @GetMapping(value = "/export")
    public Result writeExcel(InventoryCriteria criteria) {
        List<InventoryDto> inventoryDtos = inventoryService.findList(criteria);
        List<InventoryExportModel> list = new ArrayList<>();
        for (InventoryDto inventoryDto : inventoryDtos) {
            list.add(new InventoryExportModel(inventoryDto));
        }
        String fileName = "WMS库存" + System.currentTimeMillis() + ".xlsx";;
        String sheetName = "sheet1";

        EasyExcel.write(fileSetting.getStaticFileDir()+"\\"+fileName, InventoryExportModel.class).sheet(sheetName).doWrite(list);

        return ResultGenerator.genSuccessResult().setData(fileName);
    }

    @PostMapping("importExl")
    /**
     *导入erp仓库信息
     */
    public void inputErp(MultipartFile file) {
        try {
            List<Inventory> inventoryList = Excel.readExcelFile(file.getInputStream(), Inventory.class, file.getOriginalFilename());
            List<Inventory> collect = inventoryList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getErpAreaId())).collect(Collectors.toList());
            for (Inventory inventory : collect) {

                inventory.setWareId(285);
                inventory.setWareName("如高高压");
                inventory.setOrganizationId(-1);
                inventory.setOrganizationName("自有");
                inventory.setPackDetailId(33469);
                inventory.setPackDescribe("件");
                //倒过来数据没有库位, 设置默认库位
                inventory.setCellCode("KG11-05-09");
                inventory.setBoxCode(generateCode());
            }
            inventoryService.saveBatch(collect);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 生成唯一容器编码
     *
     * @return
     */
    public String generateCode() {
        //todo 导入ERP数据时容器编码重复查库会引起数据库缓慢 所以使用redis自增 如果使用当前日期会与mysql 库里的容器编码冲突,
        String db2 = RedisConstants.SOLE_CODE;
        String varietyNumber = "";
        ValueOperations<String, Integer> vo = redisTemplate.opsForValue();
        Integer number = vo.get(db2);
        if (number != null) {
            Long increment = redisTemplate.opsForValue().increment(db2, 1);
            varietyNumber = StringUtils.autoGenericCode(increment.toString(), 4);
        } else {
            vo.set(db2, 200);
            varietyNumber = StringUtils.autoGenericCode("1", 4);
        }
        StringBuilder sb = new StringBuilder();
        sb.append("CT");
        sb.append("-");
        sb.append("20220530");
        sb.append("-");
        sb.append(varietyNumber);
        return sb.toString();
    }
}
